#include <iostream>
#include <allegro5/allegro.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>

#include <vector>
#include <stack>
#include <string>

#include "controls.h"
#include "player.h"
#include "timer.h"
#include "tile.h"
#include "map.h"
#include "npc.h"
#include "game.h"
#include "animation.h"
#include "decision.h"
#include "decisiontree.h"
#include "item.h"

using namespace std;

int main(){
  //                 Initializations
  //===================================================================
  al_init();
  al_init_primitives_addon();
  al_init_image_addon();
  al_init_font_addon();
  al_init_ttf_addon();
  
  ALLEGRO_DISPLAY *display = al_create_display(640, 480); 
  ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
  
  //install keyboard and add Keyboard to the event queue
  al_install_keyboard();
  al_register_event_source(event_queue, al_get_keyboard_event_source());
 
  //install mouse and add mouse to the event queue
  al_install_mouse();
  al_register_event_source(event_queue, al_get_mouse_event_source());
 
  al_register_event_source(event_queue, al_get_display_event_source(display));
  //make new player object, hero
  
  ALLEGRO_PATH *path = al_get_standard_path(ALLEGRO_RESOURCES_PATH); 
  al_set_path_filename(path, "images/trollbot1.png");
  player hero(al_load_bitmap(al_path_cstr(path, '/')));
  
 
  al_set_path_filename(path, "images/grass1.png");
  tile grass1(path,false,16,16,0);
  al_set_path_filename(path, "images/dirt1.png");
  tile dirt1(path, true, 16,16,1);
  
  map mapA(640, 480);
  
  mapA.putTileIntoVector(&grass1);
  mapA.putTileIntoVector(&dirt1);
    
  al_set_path_filename(path, "images/armybot1.png");
  ALLEGRO_BITMAP * armybot1 = al_load_bitmap(al_path_cstr(path, '/'));
  
  
  decisionTree decT;
  decT.addPlayer(&hero);
  
  npc npcguy0(64,16,0,1,&hero,&mapA);
  npc npcguy1(16,64,0,1,&hero,&mapA);
  npc npcguy2(480,256,0,1,&hero,&mapA);
  npc npcguy3(480,112,0,1,&hero,&mapA);
  npcguy0.addWayPoints(64,16);
  npcguy0.addWayPoints(80,80);
  npcguy1.addWayPoints(16,64);
  npcguy1.addWayPoints(16,192);
  npcguy2.addWayPoints(480,256);
  npcguy2.addWayPoints(512,96);
  npcguy3.addWayPoints(480,112);
  npcguy3.addWayPoints(400,336);
  
  animation animation1;
  animation1.addToCharGraphVec(armybot1);
  
  //mapA.addAni(&animation1);
  
  game theGame(&hero);
  theGame.putMapIntoVector(&mapA);
  theGame.putNpcIntoVector(&npcguy0);
  theGame.putNpcIntoVector(&npcguy1);
  theGame.putNpcIntoVector(&npcguy2);
  theGame.putNpcIntoVector(&npcguy3);
  
  theGame.addAni(&animation1);
  theGame.addDecision(&decT);
  
  //make new control object, control
  controls control(&hero, &mapA, &theGame);
  
  //initalize the timer
  timer timer;
  al_register_event_source(event_queue, al_get_timer_event_source(timer.gTimer));
  
  //initialize the camera
  ALLEGRO_TRANSFORM camera;
  
  //Initialize Fonts
  al_set_path_filename(path, "images/courbd.ttf");
  ALLEGRO_FONT *font = al_load_ttf_font(al_path_cstr(path, '/'),16,0);
  
  
  mapA.putTilesInto2DVector();
  //decisions
  closeToPlayer96 ctp1;
  decisionTreeNode* close=&ctp1;
  closeToPlayer32 ctp2;
  decisionTreeNode* closer=&ctp2;
  moveToGoalCheck mtgc;
  decisionTreeNode* patrol=&mtgc;
  goalSetToPlayer gstp;
  decisionTreeNode* playergoal=&gstp;
  goalSetToWaypoint gstw;
  decisionTreeNode* checkpat=&gstw;
  //actions
  setGoalToPlayer sgtp;
  decisionTreeNode* movetop=&sgtp; 
  update upd;
  decisionTreeNode* updated=&upd;
  changeToNextPoint ctnp;
  decisionTreeNode* next=&ctnp;
  attackP att;
  decisionTreeNode* attack=&att;
  setGoalToWaypoint sgtwp;
  decisionTreeNode* setpat=&sgtwp;

  //Tree Structure
  close->addTrueNode(closer);
  close->addFalseNode(checkpat);
  checkpat->addTrueNode(patrol);
  checkpat->addFalseNode(setpat);
  patrol->addTrueNode(next);
  patrol->addFalseNode(updated);
  closer->addTrueNode(attack);
  closer->addFalseNode(playergoal);
  playergoal->addTrueNode(updated);
  playergoal->addFalseNode(movetop);

  decT.addNodeToTree(close);

  item screwDriver("Screw Driver of Suffering", 10);
  item noodle("Wet Noodle",2);
  hero.addToItemVector(&screwDriver);
  npcguy0.addItems(&noodle);
  npcguy1.addItems(&noodle);
  npcguy2.addItems(&noodle);
  npcguy3.addItems(&noodle);
  //If true the while loop will finnish
  bool exit = false;
  al_flip_display();
  
  //start the game timer
  timer.startTimer();
  //                    Start Game Loop
  //====================================================================
  while(!(control.isExit()))
  {
	ALLEGRO_EVENT ev;
	al_wait_for_event(event_queue, &ev);
	
	control.masterChecks(ev);
	theGame.npcControl();
	//=============Move camera==============
	mapA.cameraUpdate(hero.x, hero.y);
	
	al_identity_transform(&camera);
	al_translate_transform(&camera, -(mapA.camera_x), -(mapA.camera_y));
	al_use_transform(&camera);
	//=============Draw Screen===============
	if(control.redraw&&al_is_event_queue_empty(event_queue)){
	 control.redrawFalse();
	 theGame.drawScene();
	 control.drawSpot();
	//Testing
	al_draw_textf(font, al_map_rgb(255,255,255),mapA.camera_x, mapA.camera_y, 0, "CAMERA X: %d CAMERA Y: %d", mapA.camera_x, mapA.camera_y);
	al_draw_textf(font, al_map_rgb(255,255,255),mapA.camera_x, mapA.camera_y+12, 0, "PLAYER X: %d PLAYER Y: %d", hero.x, hero.y);
	al_draw_textf(font, al_map_rgb(255,255,255),mapA.camera_x, mapA.camera_y+24, 0, "Mouse X: %d Mouse Y: %d", control.mouse_x, control.mouse_y);
	 al_flip_display();
	 al_clear_to_color(al_map_rgb(0,0,0));
	}
  }	
 al_destroy_display(display);
 al_destroy_event_queue(event_queue);
 timer.destroyTimer();
 
 return 0;
}
